home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
psp.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-09-10
|
6KB
|
147 lines
{
USING THE PROGRAM SEGMENT PREFIX (PSP) AS
A TURBO PASCAL RECORD
GARRY J. VASS [72307,3311]
The program segement prefix is created by DOS
whenever a program is initiated. It is 256 decimal
bytes (100 hexidecimal bytes) long and contains a
mixed-bag of information that can be used by a Turbo
program. Some of the information in the PSP has
been made obsolete by:
1. New releases of DOS; and
2. New releases of Turbo Pascal.
For example, location 80 hex (128 decimal) contains
the length of the command tail. Locations 81 hex
and beyond contain the tail itself (the "command
tail", by the way, are the parameters passed to
a program. In the case of "format" the tail con-
tains a drive specification, system option, and
label option, such as, "a:/s/v".). The old days
of de-coding the command tail are gone, however,
replaced by Turbo's PARAMSTR(1), PARAMSTR(2), etc.
functions.
The File Control Blocks (FCB) went out with DOS 3,
although it is still possible to use them.
But several interesting items remain that can be
found conveniently only in the PSP:
1. The address of the environment string; and
2. The amount of memory available.
The segment address of the environment string is located
at PSP address 2C hex (44 decimal). This is equivalent
to absolute address CSEG:002C. (NOTE: If you are using
debug, pepores, corelook, etc to check this out, remember
that it will appear in low-byte-followed-by-high-byte
format.)
Decoding the environment string works as follows:
1. Set Eseg to MEM[Cseg:2C], or PSP.ENVIRONMENT_SEGMENT.
Start with offset address zero;
2. Concatenate the character value of
the byte at Eseg:offset to a character string;
3. Increment the offset address and
repeat step 2.
4. If the byte at Eseg:offset is equal to zero,
then one string has been found.
5. If two consequtive bytes are equal to zero,
then you have reached the end of the environment
area.
Normally, the environment strings are 10 hex paragraphs long
(or 160 decimal bytes). Some folks patch command.com and others
use config.sys options to reset this value, and as Turbo programmers,
we must accomodate them. (The easiest way to give yourself more
environment space is to use the SHELL statement in your config.sys
file. For example: SHELL=C:\COMMAND.COM /P /E:20, will give you
20 hex paragraphs.) This, combined with Turbo's limitation of
255 decimal bytes for a maximum string length, means that a REPEAT/
UNTIL construct is necessary.
Another item worth checking is the memory size DOS thinks it has.
This is given in Cseg:0002, or PSP.MEMORY_SIZE_IN_PARAGRAPHS.
The functions, ENVIRONMENT and MEMORY, provide at least one way
of getting at these values.
}
PROGRAM PSP;
TYPE
ANYSTRING = STRING[255];
PSPAREA = RECORD
INT_20_INSTRUCTION :INTEGER;
MEMORY_SIZE_IN_PARAGRAPHS :INTEGER;
RESERVED_BYTE :BYTE;
CALL_TO_DOS :ARRAY[1..05] OF BYTE;
TERMINATE_VECTOR :ARRAY[1..02] OF INTEGER;
BREAK_VECTOR :ARRAY[1..02] OF INTEGER;
ERROR_VECTOR :ARRAY[1..02] OF INTEGER;
USED_BY_DOS :ARRAY[1..22] OF BYTE;
ENVIRONMENT_SEGMENT :INTEGER;
DOS_WORK_AREA :ARRAY[1..34] OF BYTE;
INT21_INSTRUCTIONS :ARRAY[1..03] OF BYTE;
MORE_RESERVED :INTEGER;
FCB_1_EXTENSION :ARRAY[1..07] OF BYTE;
FCB_1 :ARRAY[1..09] OF BYTE;
FCB_2_EXTENSION :ARRAY[1..07] OF BYTE;
FCB_2 :ARRAY[1..20] OF BYTE;
PARAMETER_LENGTH :BYTE;
PARAMETERS :ARRAY[1..127] OF CHAR;
END;
VAR
PSP :PSPAREA ABSOLUTE CSEG:$0000;
I :INTEGER;
OFFSET :INTEGER;
MORE :BOOLEAN;
FUNCTION REALNUMBER(R:INTEGER):REAL;
BEGIN
IF R < 0 THEN REALNUMBER := 65536.0 + R
ELSE REALNUMBER := R;
END;
FUNCTION ENVIRONMENT(SEGMENT:INTEGER;VAR OFF:INTEGER; VAR MORE:BOOLEAN):ANYSTRING;
{GET THE NEXT ASCIIZ STRING FROM THE ENVIRONMENT}
VAR
T : ANYSTRING;
OFFSET : INTEGER;
BEGIN
T := '';
OFFSET := OFF;
REPEAT
T := T + CHR(MEM[SEGMENT:OFFSET]);
OFFSET := SUCC(OFFSET);
UNTIL (MEM[SEGMENT:OFFSET] = 0);
IF (MEM[SEGMENT:OFFSET + 0] = 0) AND
(MEM[SEGMENT:OFFSET + 1] = 0) THEN MORE := FALSE
ELSE MORE := TRUE;
ENVIRONMENT := T;
OFF := OFFSET;
END;
FUNCTION MEMORY(MEMORYSIZE:INTEGER):REAL;
BEGIN
MEMORY := REALNUMBER(MEMORYSIZE) * 16;
END;
BEGIN
OFFSET := 0;
REPEAT
WRITELN('ENVIRONMENT STRING = ',ENVIRONMENT(PSP.ENVIRONMENT_SEGMENT,OFFSET,MORE));
UNTIL NOT MORE;
WRITELN('DOS THINKS IT HAS ',MEMORY(PSP.MEMORY_SIZE_IN_PARAGRAPHS):10:0,' BYTES AVAILABLE');
END.
y:
1. New releases of DOS; and
2. New releases of Turbo Pascal.
For examp